<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    function customInstanceof(obj,constr){
        if (obj === null || typeof obj !== 'object'){
            return false
        }
        if (typeof constr !== 'function'){
            throw new TypeError('原型需要是函数类型')
        }
        const constrProto = constr.prototype
        let proto = Object.getPrototypeOf(obj)
        while(proto){
            if (proto === constrProto){
							return true
            }
            proto = Object.getPrototypeOf(proto)
        }
        return false
    }
		
		// 测试 1：数组是 Array 的实例
console.log(customInstanceof([], Array));    // true
console.log(customInstanceof([], Object));   // true (Array 继承自 Object)
console.log([] instanceof Array);            // 原生结果 true

// 测试 2：普通对象是 Object 的实例
console.log(customInstanceof({}, Object));   // true
console.log({} instanceof Object);           // 原生结果 true

    // 测试 3：原型链继承验证
class Animal {}
class Dog extends Animal {}
const dog = new Dog();

console.log(customInstanceof(dog, Dog));     // true
console.log(customInstanceof(dog, Animal));  // true
console.log(customInstanceof(dog, Object));  // true
    
    // 测试 4：原始类型返回 false
console.log(customInstanceof(123, Number));  // false（原始类型）
console.log(customInstanceof("abc", String));// false
console.log(customInstanceof(true, Boolean));// false

// 测试 5：null/undefined 处理
console.log(customInstanceof(null, Object)); // false
console.log(customInstanceof(undefined, Object)); // false


    // 测试 6：非函数构造函数报错
try {
    customInstanceof({}, "not_a_function"); // 预期抛出 TypeError
} catch (e) {
    console.log(e.message);  // 应输出 "原型需要是函数类型"
}

// 测试 7：与原生 instanceof 结果一致
function Person() {}
const person = new Person();

console.log(customInstanceof(person, Person) === (person instanceof Person));  // true
console.log(customInstanceof([], Object) === ([] instanceof Object));          // true

</script>
</html>